home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
rpg
/
crossfir.92
/
crossfir
/
crossfire-0.92.5
/
server
/
login.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-24
|
24KB
|
805 lines
/*
* static char *rcsid_login_c =
* "$Id: login.c,v 1.40 1996/01/02 11:40:40 master Exp $";
*/
/*
CrossFire, A Multiplayer game for X-windows
Copyright (C) 1992 Frank Tore Johansen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The author can be reached via e-mail to frankj@ifi.uio.no.
*/
#include <global.h>
#ifndef __CEXTRACT__
#include <sproto.h>
#endif
#include <spells.h>
extern spell spells[NROFREALSPELLS];
extern void sub_weight (object *, signed long);
extern void add_weight (object *, signed long);
extern char *uncomp[NROF_COMPRESS_METHODS][3];
extern char *range_name[range_size];
extern long pticks;
/* If flag is non zero, it means that we want to try and save everyone, but
* keep the game running. Thus, we don't want to free any information.
*/
void emergency_save(int flag) {
player *pl;
#ifndef NO_EMERGENCY_SAVE
trying_emergency_save = 1;
if(editor)
return;
LOG(llevError,"Emergency save: ");
for(pl=first_player;pl!=NULL;pl=pl->next) {
if(!pl->ob) {
LOG(llevError, "No name, ignoring this.\n");
continue;
}
LOG(llevError,"%s ",pl->ob->name);
new_draw_info(NDI_UNIQUE, 0,pl->ob,"Emergency save...");
/* If we are not exiting the game (ie, this is sort of a backup save), then
* don't change the location back to the village. Note that there are other
* options to have backup saves be done at the starting village
*/
if (!flag) {
strcpy(pl->maplevel, first_map_path);
if(pl->ob->map!=NULL)
pl->ob->map = NULL;
pl->ob->x = -1;
pl->ob->y = -1;
}
if(!save_player(pl->ob,flag)) {
LOG(llevError, "(failed) ");
new_draw_info(NDI_UNIQUE, 0,pl->ob,"Emergency save failed, checking score...");
}
check_score(pl->ob);
}
LOG(llevError,"\n");
#else
LOG(llevError,"Emergency saves disabled, no save attempted\n");
#endif
/* After we complete the emergency saves, then try and free
* the pixmaps. Without this effort, some X-Terminals (and maybe
* even workstations) XServers will not free the space used by
* the pixmaps. This is more of a problem for the X-Terminals,
* because they don't have a lot of memory. The pointer is set
* to NULL after we are finished to prevent another effort later.
*/
if (!flag) {
for(pl=first_player;pl!=NULL;pl=pl->next) {
if(!pl->ob) {
LOG(llevError, "No name, ignoring this.\n");
continue;
}
if (pl->pixmaps) {
free_pixmaps(pl->gdisp, pl->pixmaps);
pl->pixmaps=NULL;
}
if (pl->masks) {
free_pixmaps(pl->gdisp, pl->masks);
pl->masks =NULL;
}
}
}
}
void delete_character(char *name) {
char buf[MAX_BUF];
#ifdef SAVE_HOMEDIR
sprintf(buf,"%s/%s/%s.pl",(char *) getenv("HOME"),PlayerDir,name);
#else
sprintf(buf,"%s/%s/%s.pl",LibDir,PlayerDir,name);
#endif
if(unlink(buf)== -1 && debug)
perror("crossfire (delete character)");
}
void remove_lock(player *pl) {
#ifdef LOCK_PLAYER
char buf[MAX_BUF];
if(pl->ob == NULL)
return;
#ifdef SAVE_HOMEDIR
sprintf(buf, "%s/%s", (char *) getenv("HOME"), PlayerDir);
(void) create_savedir_if_needed(buf);
sprintf(buf,"%s/%s/%s.lock",(char *) getenv("HOME"),PlayerDir,pl->ob->name);
#else
sprintf(buf,"%s/%s/%s.lock",LibDir,PlayerDir,pl->ob->name);
#endif
if(!rmdir(buf)) {
#ifdef DEBUG
perror("Couldn't remove lockfile(dir)");
#endif
}
#endif
}
int lock_player(char *name) {
#ifdef LOCK_PLAYER
char buf[MAX_BUF];
#ifdef SAVE_HOMEDIR
sprintf(buf, "%s/%s", (char *) getenv("HOME"), PlayerDir);
(void) create_savedir_if_needed(buf);
sprintf(buf,"%s/%s/%s.lock",(char *) getenv("HOME"),PlayerDir,name);
#else
sprintf(buf,"%s/%s/%s.lock",LibDir,PlayerDir,name);
#endif
if(!mkdir(buf,0770))
return 0;
if(errno != EEXIST) {
perror("Couldn't create lockfile(dir)");
return 1;
}
return 1;
#else
return 0;
#endif
}
int check_name(player *me,char *name) {
player *pl;
#ifdef ONE_PLAYER_PR_UID
if (me->username == NULL)
LOG(llevError, "Player had no username.\n");
else
for (pl = first_player; pl != NULL; pl = pl->next)
if (pl != me && pl->username != NULL &&
!strcmp(pl->username, me->username)) {
new_draw_info(NDI_UNIQUE, 0,me->ob, "You are already playing the game.");
return 0;
}
#endif
for(pl=first_player;pl!=NULL;pl=pl->next)
if(pl!=me&&pl->ob->name!=NULL&&!strcmp(pl->ob->name,name)) {
new_draw_info(NDI_UNIQUE, 0,me->ob,"That name is already in use.");
return 0;
}
if(lock_player(name)) {
new_draw_info(NDI_UNIQUE, 0,me->ob,"That name is already in use.");
return 0;
}
if(!playername_ok(name)) {
new_draw_info(NDI_UNIQUE, 0,me->ob,"That name contains illegal characters.");
remove_lock(me);
return 0;
}
return 1;
}
int create_savedir_if_needed(char *savedir)
{
struct stat *buf;
if ((buf = (struct stat *) malloc(sizeof(struct stat))) == NULL) {
perror("Unable to save playerfile... out of memory.");
return 0;
} else {
stat(savedir, buf);
if ((buf->st_mode & S_IFDIR) == 0)
#if defined(_IBMR2) || defined(___IBMR2)
if (mkdir(savedir, S_ISUID|S_ISGID|S_IRUSR|S_IWUSR|S_IXUSR))
#else
if (mkdir(savedir, S_ISUID|S_ISGID|S_IREAD|S_IWRITE|S_IEXEC))
#endif
{
perror("Unable to create player savedir,");
perror(savedir);
return 0;
}
free(buf);
}
return 1;
}
void destroy_object (object *op)
{
object *tmp;
while ((tmp = op->inv))
destroy_object (tmp);
if (!QUERY_FLAG(op, FLAG_REMOVED))
remove_ob(op);
free_object(op);
}
/*
* If flag is set, it's only backup, ie dont remove objects from inventory
* If BACKUP_SAVE_AT_HOME is set, and the flag is set, then the player
* will be saved at the emergency save location.
* Returns non zero if successful.
*/
int save_player(object *op, int flag) {
FILE *fp;
char filename[MAX_BUF], *tmpfilename,backupfile[MAX_BUF];
object *tmp, *container=NULL;
player *pl = op->contr;
int i;
long checksum;
#ifdef BACKUP_SAVE_AT_HOME
sint16 backup_x, backup_y;
#endif
flag&=1;
if(QUERY_FLAG(op,FLAG_WAS_WIZ)||!pl->name_changed||(!flag&&!op->stats.exp)) {
if(!flag) {
new_draw_info(NDI_UNIQUE, 0,op,"Your name is not valid,");
new_draw_info(NDI_UNIQUE, 0,op,"Game not saved.");
}
return 0;
}
if (flag == 0)
terminate_all_pets(op);
#ifdef SAVE_HOMEDIR
sprintf(filename,"%s/%s", (char *) getenv("HOME"), PlayerDir);
(void) create_savedir_if_needed(filename);
sprintf(filename,"%s/%s/%s.pl",(char *) getenv("HOME"),PlayerDir,op->name);
#else
sprintf(filename,"%s/%s/%s.pl",LibDir,PlayerDir,op->name);
#endif
tmpfilename = tempnam(TMPDIR,NULL);
fp=fopen(tmpfilename, "w");
if(!fp) {
new_draw_info(NDI_UNIQUE, 0,op, "Can't open file for save.");
free(tmpfilename);
return 0;
}
/* Eneq(@csd.uu.se): If we have an open container hide it. */
if (op->container) {
container=op->container;
op->container=NULL;
}
fprintf(fp,"password %s\n",pl->password);
#ifdef SET_TITLE
if(pl->own_title[0]!='\0')
fprintf(fp,"title %s\n",pl->own_title);
#endif /* SET_TITLE */
#ifdef SAVE_WINDOW_POSITIONS
if(pl->valid_save_positions && pl->split_window) {
fprintf(fp,"win_pos");
for(i=0;i<6;i++)
fprintf(fp," %d %d %u %u",
pl->win_pos[i].x,pl->win_pos[i].y,
pl->win_pos[i].w,pl->win_pos[i].h);
fprintf(fp,"\n");
}
#endif /* SAVE_WINDOW_POSITIONS */
#ifdef EXPLORE_MODE
fprintf(fp,"explore %d\n",pl->explore);
#endif
fprintf(fp,"gen_hp %d\n",pl->gen_hp);
fprintf(fp,"gen_sp %d\n",pl->gen_sp);
fprintf(fp,"gen_grace %d\n",pl->gen_grace);
fprintf(fp,"listening %d\n",pl->listening);
fprintf(fp,"spell %d\n",pl->chosen_spell);
fprintf(fp,"shoottype %d\n",pl->shoottype);
fprintf(fp,"berzerk %d\n",pl->berzerk);
fprintf(fp,"peaceful %d\n",pl->peaceful);
fprintf(fp,"scroll %d\n",pl->scroll);
fprintf(fp,"digestion %d\n",pl->digestion);
fprintf(fp,"pickup %d\n", pl->mode);
fprintf(fp,"keyboard_flush %d\n", pl->keyboard_flush);
fprintf(fp,"show_inv_icon %d\n", pl->show_inv_icon);
fprintf(fp,"outputs_sync %d\n", pl->outputs_sync);
fprintf(fp,"outputs_count %d\n", pl->outputs_count);
#ifdef BACKUP_SAVE_AT_HOME
if (op->map!=NULL && flag==0)
#else
if (op->map!=NULL)
#endif
fprintf(fp,"map %s\n",op->map->path);
else
fprintf(fp,"map %s\n",first_map_path);
fprintf(fp,"weapon_sp %f\n",pl->weapon_sp);
fprintf(fp,"Str %d\n",pl->orig_stats.Str);
fprintf(fp,"Dex %d\n",pl->orig_stats.Dex);
fprintf(fp,"Con %d\n",pl->orig_stats.Con);
fprintf(fp,"Int %d\n",pl->orig_stats.Int);
fprintf(fp,"Pow %d\n",pl->orig_stats.Pow);
fprintf(fp,"Wis %d\n",pl->orig_stats.Wis);
fprintf(fp,"Cha %d\n",pl->orig_stats.Cha);
dump_keys(pl, fp);
fprintf(fp,"lev_array %d\n",op->level>10?10:op->level);
for(i=1;i<=pl->last_level&&i<=10;i++) {
fprintf(fp,"%d\n",pl->levhp[i]);
fprintf(fp,"%d\n",pl->levsp[i]);
fprintf(fp,"%d\n",pl->levgrace[i]);
}
for(i=0;i<pl->nrofknownspells;i++)
fprintf(fp,"known_spell %s\n",spells[pl->known_spells[i]].name);
fprintf(fp,"endplst\n");
pl->freeze_inv = 1;
SET_FLAG(op, FLAG_NO_FIX_PLAYER);
#ifdef BACKUP_SAVE_AT_HOME
if (flag) {
backup_x = op->x;
backup_y = op->y;
op->x = -1;
op->y = -1;
}
/* Save objects, but not unpaid objects. Don't remove objects from
* inventory.
*/
save_object(fp, op, 2);
if (flag) {
op->x = backup_x;
op->y = backup_y;
}
#else
save_object(fp, op, 3); /* don't check and don't remove */
#endif
CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
if(!flag)
while ((tmp = op->inv))
destroy_object (tmp);
if (fclose(fp) == EOF) { /* make sure the write succeeded */
new_draw_info(NDI_UNIQUE, 0,op, "Can't save character.");
unlink(tmpfilename);
free(tmpfilename);
return 0;
}
checksum = calculate_checksum(tmpfilename, 0);
sprintf(backupfile, "%s.tmp", filename);
rename(filename, backupfile);
fp = fopen(filename,"w");
if(!fp) {
new_draw_info(NDI_UNIQUE, 0,op, "Can't open file for save.");
unlink(tmpfilename);
free(tmpfilename);
return 0;
}
fprintf(fp,"checksum %lx\n",checksum);
copy_file(tmpfilename, fp);
unlink(tmpfilename);
free(tmpfilename);
if (fclose(fp) == EOF) { /* got write error */
new_draw_info(NDI_UNIQUE, 0,op, "Can't close file for save.");
rename(backupfile, filename); /* Restore the original */
return 0;
}
else
unlink(backupfile);
pl->freeze_inv=0;
/* Eneq(@csd.uu.se): Reveal the container if we have one. */
if (flag&&container!=NULL)
op->container = container;
if(!flag)
if (op->contr->eric_server > 0)
esrv_send_inventory(op, op);
else
draw_all_inventory(op);
chmod(filename,SAVE_MODE);
return 1;
}
/*
* calculate_checksum:
* Evil scheme to avoid tampering with the player-files 8)
* The cheat-flag will be set if the file has been changed.
*/
long calculate_checksum(char *filename, int checkdouble) {
#ifdef USE_CHECKSUM
long checksum = 0;
int offset = 0;
FILE *fp;
char buf[MAX_BUF], *cp;
if ((fp = fopen(filename,"r")) == NULL)
return 0;
while(fgets(buf,MAX_BUF,fp)) {
if(checkdouble && !strncmp(buf,"checksum",8))
continue;
for(cp=buf;*cp;cp++) {
if(++offset>28)
offset = 0;
checksum^=(*cp<<offset);
}
}
fclose(fp);
return checksum;
#else
return 0;
#endif
}
void copy_file(char *filename, FILE *fpout) {
FILE *fp;
char buf[MAX_BUF];
if((fp = fopen(filename,"r")) == NULL)
return;
while(fgets(buf,MAX_BUF,fp)!=NULL)
fputs(buf,fpout);
fclose(fp);
}
#if 1
static int spell_sort(const void *a1,const void *a2)
{
return strcmp(spells[(int)*(sint16 *)a1].name,spells[(int)*(sint16 *)a2].name);
}
#else
static int spell_sort(const char *a1,const char *a2)
{
fprintf(stderr, "spell1=%d, spell2=%d\n", *(sint16*)a1, *(sint16*)a2);
return strcmp(spells[(int )*a1].name,spells[(int )*a2].name);
}
#endif
void check_login(object *op) {
FILE *fp;
char filename[MAX_BUF];
char buf[MAX_BUF],bufall[MAX_BUF];
int i,value,x,y,comp;
long checksum = 0;
player *pl = op->contr;
strcpy (pl->maplevel, first_map_path);
#ifdef SAVE_HOMEDIR
sprintf(filename,"%s/%s/%s.pl",(char *) getenv("HOME"),PlayerDir,op->name);
#else
sprintf(filename,"%s/%s/%s.pl",LibDir,PlayerDir,op->name);
#endif
if ((fp=open_and_uncompress(filename,1,&comp)) == NULL) {
confirm_password(op);
} else {
int correct = 0;
if(fgets(bufall,MAX_BUF,fp) != NULL) {
if(!strncmp(bufall,"checksum ",9)) {
checksum = strtol_local(bufall+9,(char **) NULL, 16);
(void) fgets(bufall,MAX_BUF,fp);
}
if(sscanf(bufall,"password %s\n",buf))
/* New password scheme: */
correct=check_password(pl->write_buf+1,buf);
else { /* Old scheme when passwords were stored in ascii */
bufall[strlen(bufall)-1]='\0';
correct= !strcmp(bufall,pl->write_buf+1);
}
}
if (!correct) {
new_draw_info(NDI_UNIQUE, 0,op," ");
new_draw_info(NDI_UNIQUE, 0,op,"Wrong Password!");
new_draw_info(NDI_UNIQUE, 0,op," ");
remove_lock(pl);
if(op->name!=NULL)
free_string(op->name);
op->name=add_string("noname");
pl->last_value= -1;
draw_stats(op);
get_name(op);
} else {
#ifdef SAVE_INTERVAL
pl->last_save_time=time(NULL);
#endif /* SAVE_INTERVAL */
#ifdef SIMPLE_PARTY_SYSTEM
pl->party_number = (-1);
#endif /* SIMPLE_PARTY_SYSTEM */
#ifdef SAVE_WINDOW_POSITIONS
pl->valid_save_positions=0;
#endif /* SAVE_WINDOW_POSITIONS */
#ifdef SEARCH_ITEMS
pl->search_str[0]='\0';
#endif /* SEARCH_ITEMS */
pl->name_changed=1;
pl->orig_stats.Str=0;
pl->orig_stats.Dex=0;
pl->orig_stats.Con=0;
pl->orig_stats.Int=0;
pl->orig_stats.Pow=0;
pl->orig_stats.Wis=0;
pl->orig_stats.Cha=0;
load_default_keys(op->contr);
while (fgets(bufall,MAX_BUF,fp)!=NULL) {
sscanf(bufall,"%s %d\n",buf,&value);
if (!strcmp(buf,"endplst"))
break;
#ifdef SET_TITLE
else if (!strncmp(bufall,"title",6))
sscanf(bufall,"title %s[^\n]",pl->own_title);
#endif /* SET_TITLE */
#ifdef SAVE_WINDOW_POSITIONS
else if (!strcmp(buf,"win_pos") && pl->split_window) {
pl->valid_save_positions=
(sscanf(bufall,
"win_pos %d %d %u %u %d %d %u %u %d %d %u %u %d %d %u %u %d %d %u %u %d %d %u %u",
&pl->win_pos[0].x,&pl->win_pos[0].y,
&pl->win_pos[0].w,&pl->win_pos[0].h,
&pl->win_pos[1].x,&pl->win_pos[1].y,
&pl->win_pos[1].w,&pl->win_pos[1].h,
&pl->win_pos[2].x,&pl->win_pos[2].y,
&pl->win_pos[2].w,&pl->win_pos[2].h,
&pl->win_pos[3].x,&pl->win_pos[3].y,
&pl->win_pos[3].w,&pl->win_pos[3].h,
&pl->win_pos[4].x,&pl->win_pos[4].y,
&pl->win_pos[4].w,&pl->win_pos[4].h,
&pl->win_pos[5].x,&pl->win_pos[5].y,
&pl->win_pos[5].w,&pl->win_pos[5].h)==24);
}
#endif /* SAVE_WINDOW_POSITIONS */
#ifdef EXPLORE_MODE
else if (!strcmp(buf,"explore"))
pl->explore = value;
#endif
else if (!strcmp(buf,"gen_hp"))
pl->gen_hp=value;
else if (!strcmp(buf,"shoottype"))
pl->shoottype=(rangetype)value;
else if (!strcmp(buf,"gen_sp"))
pl->gen_sp=value;
else if (!strcmp(buf,"gen_grace"))
pl->gen_grace=value;
else if (!strcmp(buf,"spell"))
pl->chosen_spell=value;
else if (!strcmp(buf,"listening"))
pl->listening=value;
else if (!strcmp(buf,"berzerk"))
pl->berzerk=value;
else if (!strcmp(buf,"peaceful"))
pl->peaceful=value;
else if (!strcmp(buf,"scroll"))
pl->scroll=value;
else if (!strcmp(buf,"digestion"))
pl->digestion=value;
else if (!strcmp(buf,"pickup"))
pl->mode=value;
else if (!strcmp(buf,"keyboard_flush"))
pl->keyboard_flush = value;
else if (!strcmp(buf,"show_inv_icon")) {
pl->show_inv_icon = value;
if (pl->show_inv_icon)
strcpy(pl->format_inv,"%-20.20s%-6s"); /* This can be changed by resize */
else
strcpy(pl->format_inv,"%-24.24s%-6s"); /* This can be changed by resize */
}
else if (!strcmp(buf,"outputs_sync"))
pl->outputs_sync = value;
else if (!strcmp(buf,"outputs_count"))
pl->outputs_count = value;
else if (!strcmp(buf,"map"))
sscanf(bufall,"map %s", pl->maplevel);
else if (!strcmp(buf,"weapon_sp"))
sscanf(buf,"weapon_sp %f",&pl->weapon_sp);
else if (!strcmp(buf,"Str"))
pl->orig_stats.Str=value;
else if (!strcmp(buf,"Dex"))
pl->orig_stats.Dex=value;
else if (!strcmp(buf,"Con"))
pl->orig_stats.Con=value;
else if (!strcmp(buf,"Int"))
pl->orig_stats.Int=value;
else if (!strcmp(buf,"Pow"))
pl->orig_stats.Pow=value;
else if (!strcmp(buf,"Wis"))
pl->orig_stats.Wis=value;
else if (!strcmp(buf,"Cha"))
pl->orig_stats.Cha=value;
else if (!strcmp(buf,"lev_array")){
for(i=1;i<=value;i++) {
int j;
fscanf(fp,"%d\n",&j);
pl->levhp[i]=j;
fscanf(fp,"%d\n",&j);
pl->levsp[i]=j;
fscanf(fp,"%d\n",&j);
pl->levgrace[i]=j;
}
} else if (!strcmp(buf,"spell_array")) {
pl->nrofknownspells=value;
for(i=0;i<pl->nrofknownspells;i++) {
int j;
fscanf(fp,"%d\n",&j);
pl->known_spells[i]=j;
}
} else if (!strcmp(buf,"known_spell")) {
char *cp=strchr(bufall,'\n');
*cp='\0';
cp=strchr(bufall,' ');
cp++;
for(i=0;i<NROFREALSPELLS;i++)
if(!strcmp(spells[i].name,cp)) {
pl->known_spells[pl->nrofknownspells++]=i;
break;
}
if(i==NROFREALSPELLS)
LOG(llevDebug, "Error: unknown spell (%s)\n",cp);
} else if (!strcmp(buf,"confkeys")) {
LOG(llevDebug, "Ignoring old configkeys (%d)\n", value);
for(i=0; i < value; i++)
fgets(bufall, sizeof(bufall), fp);
} else if (!strcmp(buf,"pushkey")) {
LOG(llevDebug, "Ignoring old pushkey (%s)\n", bufall);
} else if (!strcmp(buf,"key")) {
insert_key(op->contr, KEYF_USER, &bufall[4]);
} else {
LOG(llevError,"Warning, oldfashioned variable in save-file: %s\n",
buf);
}
}
/* sigh */
free_object (op);
op = pl->ob = LoadObject (fp, NULL);
CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
x=op->x; y=op->y;
/* if old save file, try recover from it */
if(!op->arch) {
new_draw_info(NDI_UNIQUE, 0,op,"Error: unknown class. (probably old save file)\n");
op->arch = find_archetype (op->race);
}
if(!op->arch) { /* and fail... */
new_draw_info(NDI_UNIQUE, 0,op,"Fatal error: Can't find archetype\n");
LOG(llevError, "Error: Unknown class; %s.\n", op->race);
}
strncpy(pl->title, op->arch->clone.name,MAX_NAME);
/* If the map where the person was last saved does not exist,
* restart them in the beginning town. This is good for when
* maps change between versions
*/
if (check_path(pl->maplevel)==-1) {
strcpy(pl->maplevel, first_map_path);
x = -1;
}
enter_exit(op,NULL); /* This won't insert the player any longer! */
if (op->stats.hp<0||op->stats.food<0) {
/* IF NOT_PERMADEATH is set, this should really do something different,
* like bring the character back to life under the normal rules.
*/
clear_win_info(op);
new_draw_info(NDI_UNIQUE, 0,op,"Your character was dead, when you quit.");
new_draw_info(NDI_UNIQUE, 0,op," ");
play_again(op);
delete_character(op->name);
} else {
pl->name_changed=1;
pl->state = ST_PLAYING;
#ifdef AUTOSAVE
pl->last_save_tick = pticks;
#endif
op->carrying=0;
pl->freeze_inv=1;
pl->freeze_inv=0;
if (pl->eric_server > 0) {
esrv_new_player(pl->eric_server, op->count, op->name, op->weight,
op->face->number);
esrv_send_inventory(op, op);
} else {
draw_all_inventory(op);
}
draw_all_inventory(op);
/* Need to call fix_player now - program modified so that it is not
* called during the load process (FLAG_NO_FIX_PLAYER set when
* saved
*/
legal_range(op, op->contr->shoottype);
fix_player(op);
fix_weight ();
#ifdef ALLOW_SKILLS
(void) init_player_exp(op);
(void) link_player_skills(op);
#endif
if(!pl->split_window && pl->eric_server == 0)
XClearWindow(pl->gdisp,pl->win_root);
draw_all_info(op);
draw_all_message(op);
new_draw_info(NDI_UNIQUE, 0,op,"Welcome Back!");
if(pl->loading == NULL) {
if(!out_of_map(op->map,x,y))
op->x=x, op->y=y;
insert_ob_in_map(op,op->map);
} else {
LOG(llevError,"Warning: map was not in memory (%s).\n",
op->map->path);
pl->removed = 0; /* Pl. will be inserted when map is loaded */
}
refresh(op);
draw_all_look(op);
close_and_delete(fp, comp);
LOG(llevDebug,"Checksums: %x %x\n",
checksum,calculate_checksum(filename,1));
#ifdef CHECKSUM_ENABLED
if(calculate_checksum(filename) != checksum) {
new_draw_info(NDI_UNIQUE, 0,op,"Since your savefile has been tampered with,");
new_draw_info(NDI_UNIQUE, 0,op,"you will not be able to save again.");
set_cheat(op);
}
#endif
}
}
if (pl->state != ST_PLAYING)
close_and_delete(fp, comp);
}
pl->last_value= -1;
/* This seems to compile without warnings now. Don't know if it works
* on SGI's or not, however.
*/
qsort((void *)pl->known_spells,pl->nrofknownspells,
sizeof(pl->known_spells[0]),(int (*)())spell_sort);
draw_stats(op);
#ifdef SAVE_WINDOW_POSITIONS
if(pl->valid_save_positions && pl->split_window) {
unsigned long xwc_mask=0;
XWindowChanges xwc;
xwc_mask=CWX|CWY|CWWidth|CWHeight;
xwc.x=pl->win_pos[0].x;xwc.y=pl->win_pos[0].y;
xwc.width=pl->win_pos[0].w;xwc.height=pl->win_pos[0].h;
XConfigureWindow(pl->gdisp,pl->win_game,xwc_mask,&xwc);
xwc.x=pl->win_pos[1].x;xwc.y=pl->win_pos[1].y;
xwc.width=pl->win_pos[1].w;xwc.height=pl->win_pos[1].h;
XConfigureWindow(pl->gdisp,pl->win_stats,xwc_mask,&xwc);
xwc.x=pl->win_pos[2].x;xwc.y=pl->win_pos[2].y;
xwc.width=pl->win_pos[2].w;xwc.height=pl->win_pos[2].h;
XConfigureWindow(pl->gdisp,pl->win_info,xwc_mask,&xwc);
xwc.x=pl->win_pos[3].x;xwc.y=pl->win_pos[3].y;
xwc.width=pl->win_pos[3].w;xwc.height=pl->win_pos[3].h;
XConfigureWindow(pl->gdisp,pl->win_inv,xwc_mask,&xwc);
xwc.x=pl->win_pos[4].x;xwc.y=pl->win_pos[4].y;
xwc.width=pl->win_pos[4].w;xwc.height=pl->win_pos[4].h;
XConfigureWindow(pl->gdisp,pl->win_look,xwc_mask,&xwc);
xwc.x=pl->win_pos[5].x;xwc.y=pl->win_pos[5].y;
xwc.width=pl->win_pos[5].w;xwc.height=pl->win_pos[5].h;
XConfigureWindow(pl->gdisp,pl->win_message,xwc_mask,&xwc);
}
#endif /* SAVE_WINDOW_POSITIONS */
return;
}